import Vue from 'vue'
import Cookies from 'js-cookie'
import FileSaver from 'file-saver'
import JSZip from 'jszip'
import XLSX from 'xlsx'
import store from '@/store'
import { Message } from 'element-ui'

Vue.prototype.setSessionStorage = function (key, value) {
  window.sessionStorage.setItem(key, value)
}
Vue.prototype.getSessionStorage = function (key) {
  const value = window.sessionStorage.getItem(key)
  if (!value || value === '') {
    return ''
  }
  return value
}
Vue.prototype.removeSessionStorage = function (key) {
  window.sessionStorage.removeItem(key)
}
Vue.prototype.setCookie = function (key, value) {
  Cookies.set(key, value)
}
Vue.prototype.getCookie = function (key) {
  const value = Cookies.get(key)
  if (!value || value === '') {
    return ''
  }
  return value
}
Vue.prototype.removeCookie = function (key) {
  Cookies.remove(key)
}
Vue.prototype.setLocalStorage = function (key, value) {
  if (!value) {
    window.localStorage.setItem(key, '')
  } else {
    window.localStorage.setItem(key, value)
  }
}
Vue.prototype.getLocalStorage = function (key) {
  const value = window.localStorage.getItem(key)
  if (!value || value === '') {
    return ''
  }
  return value
}
Vue.prototype.removeLocalStorage = function (key) {
  window.localStorage.removeItem(key)
}
Vue.prototype.checkToken = function (key) {
  const reg = /^AUTH_[0-9A-Za-z]{22}$/
  return reg.test(key)
}

Vue.prototype.randomString = function (e) {
  e = e || 32
  let n = '0123456789'
  let t = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz1234567890'
  let res = ''
  for (let i = 0; i < e - 1; i++) {
    res += t.charAt(Math.floor(Math.random() * t.length))
  }
  let index = Math.floor(Math.random() * res.length)
  return res.slice(0, index) + n.charAt(Math.floor(Math.random() * n.length)) + res.slice(index)
}

Vue.prototype.baseUrl = process.env.baseDomain + process.env.baseApi

Vue.prototype.getFileSize = function (fileByte) {
  var fileSizeByte = fileByte
  var fileSizeMsg = ''
  if (fileSizeByte < 1048576) fileSizeMsg = (fileSizeByte / 1024).toFixed(2) + 'KB'
  else if (fileSizeByte === 1048576) fileSizeMsg = '1MB'
  else if (fileSizeByte > 1048576 && fileSizeByte < 1073741824) fileSizeMsg = (fileSizeByte / (1024 * 1024)).toFixed(2) + 'MB'
  else if (fileSizeByte > 1048576 && fileSizeByte === 1073741824) fileSizeMsg = '1GB'
  else if (fileSizeByte > 1073741824 && fileSizeByte < 1099511627776) fileSizeMsg = (fileSizeByte / (1024 * 1024 * 1024)).toFixed(2) + 'GB'
  else fileSizeMsg = '文件超过1TB'
  return fileSizeMsg
}

Vue.prototype.getDict = function (key) {
  const value = store.getters.dictList[key]
  if (!value) {
    return new Promise((resolve) => {
      Vue.prototype.fetch(Vue.prototype.apiType.common.getDict, {dictId: key}, null, responseData => {
        const dict = responseData.data
        const obj = {}
        obj.key = key
        obj.value = dict
        store.dispatch('GenerateDict', obj).then(() => {
        })
        resolve(responseData.data)
      })
    })
  } else {
    return new Promise((resolve) => {
      resolve(value)
    })
  }
}

Vue.prototype.getDictList = function (key, callback) {
  const value = store.getters.dictList[key]
  if (!value) {
    Vue.prototype.fetch(Vue.prototype.apiType.common.getDict, {dictId: key}, null, responseData => {
      const dict = responseData.data
      const obj = {}
      obj.key = key
      obj.value = dict
      store.dispatch('GenerateDict', obj).then(() => {
      })
      callback(dict)
    })
  } else {
    callback(value)
  }
}

Vue.prototype.getDictTree = function (key) {
  const value = store.getters.dictList[key]
  if (!value) {
    return new Promise((resolve) => {
      Vue.prototype.fetch(Vue.prototype.apiType.common.getDictTree, {dictTreeId: key}, null, responseData => {
        const dict = responseData.data
        const obj = {}
        obj.key = key
        obj.value = dict
        store.dispatch('GenerateDict', obj).then(() => {
        })
        resolve(responseData.data)
      })
    })
  } else {
    return new Promise((resolve) => {
      resolve(value)
    })
  }
}

Vue.prototype.getBlob = function (url) {
  return new Promise((resolve) => {
    const xhr = new XMLHttpRequest()

    xhr.open('GET', url, true)
    xhr.responseType = 'blob'
    xhr.onload = () => {
      resolve(xhr)
    }

    xhr.send()
  })
}

/**
 * 下载远程资源文件
 * @param remote: url: 下载文件的路径, fileName: 下载文件名称
 * @return File
 */
Vue.prototype.downloadFile = function download (remote) {
  return new Promise((resolve, reject) => {
    const {
      url,
      fileName
    } = remote
    if (url == null || url === '') {
      reject(remote)
    } else {
      Vue.prototype.getBlob(url).then((xhr) => { // 下载文件, 并存成ArrayBuffer对象
        if (xhr.status === 200) {
          const file = new File([xhr.response], fileName)
          resolve(file)
        } else {
          reject(xhr)
        }
      }).catch((err) => {
        reject(err)
      })
    }
  })
}

/**
 * 批量打包zip包下载
 * @param remoteArr Array [{url: 下载文件的路径, fileName: 下载文件名称}]
 * @param filename zip文件名
 */
Vue.prototype.downloadZipFile = function download (remoteArr, filename) {
  if (!remoteArr.length > 0) return
  const zip = new JSZip()
  const cache = {}
  const promises = []
  remoteArr.forEach((item) => {
    const promise = Vue.prototype.getBlob(item.url).then((xhr) => { // 下载文件, 并存成ArrayBuffer对象
      if (xhr.status === 200) {
        zip.file(item.fileName, xhr.response, {binary: true}) // 逐个添加文件
        cache[item.fileName] = xhr.response
      }
    })
    promises.push(promise)
  })
  Promise.all(promises).then(() => {
    zip.generateAsync({type: 'blob'}).then((content) => { // 生成二进制流
      FileSaver.saveAs(content, `${filename}.zip`) // 利用file-saver保存文件
    })
  })
}

Vue.prototype.exportExcelFile = function exportExcel (document, tableId, fileName) {
  /* generate workbook object from table */
  let wb = XLSX.utils.table_to_book(document.querySelector('#' + tableId))
  /* get binary string as output */
  let wbout = XLSX.write(wb, {bookType: 'xlsx', bookSST: true, type: 'array'})
  try {
    fileName = fileName.endsWith('.xlsx') ? fileName : fileName + '.xlsx'
    FileSaver.saveAs(new Blob([wbout], {type: 'application/octet-stream'}), fileName)
  } catch (e) {
    if (typeof console !== 'undefined') {
      console.log(e, wbout)
    }
  }
  return wbout
}

Vue.prototype.getDisplay = function (value, valueList) {
  for (const display in valueList) {
    if (valueList[display].value === value) {
      return valueList[display].label
    }
  }
}

Vue.prototype.formatDate = function (inputTime) {
  const date = new Date(inputTime)
  if (!(date instanceof Date) || isNaN(date.getTime())) {
    return
  }
  let month = date.getMonth() + 1
  let strDate = date.getDate()
  if (month >= 1 && month <= 9) {
    month = '0' + month
  }
  if (strDate >= 0 && strDate <= 9) {
    strDate = '0' + strDate
  }
  let hour = date.getHours()
  if (hour >= 0 && hour <= 9) {
    hour = '0' + hour
  }
  let minutes = date.getMinutes()
  if (minutes >= 0 && minutes <= 9) {
    minutes = '0' + minutes
  }
  let seconds = date.getSeconds()
  if (seconds >= 0 && seconds <= 9) {
    seconds = '0' + seconds
  }
  return date.getFullYear() + '-' + month + '-' + strDate +
    ' ' + hour + ':' + minutes + ':' + seconds
}

Vue.prototype.isEmpty = function (data) {
  if (data === undefined || data == null) {
    return true
  }
  if (data instanceof Array) {
    if (data.length === 0) {
      return true
    }
  }
  if (data instanceof Map) {
    if (data.size === 0) {
      return true
    }
  }
  if (typeof data === 'string') {
    if (data.length === 0 || data === '') {
      return true
    }
  }
  return false
}

Vue.prototype.isNotEmpty = function (data) {
  return !Vue.prototype.isEmpty(data)
}

Vue.prototype.assert = function (condition, msg) {
  if (!condition) {
    Message.error({ message: msg })
    throw new Error(msg)
  }
}

Vue.prototype.getQueryObject = function (url) {
  url = url == null ? window.location.href : url
  const search = url.substring(url.lastIndexOf('?') + 1).split('#')[0]
  const obj = {}
  const reg = /([^?&=]+)=([^?&=]*)/g
  search.replace(reg, (rs, $1, $2) => {
    const name = decodeURIComponent($1)
    let val = decodeURIComponent($2)
    val = String(val)
    obj[name] = val
    return rs
  })
  return obj
}

Vue.prototype.forceBtnBlur = function (e) {
  let target = e.target
  if (target.nodeName === 'SPAN' || target.nodeName === 'I') {
    target = e.target.parentNode
  }
  target.blur()
}

export default {}
